home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
123_01
/
ar1.bds
< prev
next >
Wrap
Text File
|
1985-03-09
|
14KB
|
790 lines
/*
archive - BDS C version
translated from Software Tools ar/ver1.rat by:
Oscar Goldman
1221 Knox Road
Wynnewood, PA 19096
converted to use BDS C library by:
Edward K. Ream
1850 Summit Ave.
Madison, WI 53705
(608) 231 -2952
version: May 5, 1982; February 24, 1983
*/
#include "bdscio.h"
#include "dio.h"
#include "date.h"
#define MAXLINE 300 /* maximum line size */
#define MAXCHARS 30
#define NEWLINE '\n'
#define EOS 0
#define YES 1
#define NO 0
#define MAXFILES 100 /* maximum number of files processable */
#define SYS_MAXFN 15
#define DELETE_CMD 'd' /* delete member from archive */
#define PRINT_CMD 'p' /* print archive members */
#define TABLE_CMD 't' /* print table of contents */
#define UPDATE_CMD 'u' /* update archive member */
#define VERBOSE_CMD 'v' /* controls amount of output */
#define EXTRACT_CMD 'x' /* extract archive member */
#define USAGE_MESSAGE "usage: ar1 [-](dptux)[v] archive [files]\n"
#define HEADER_STRING "#-h-"
#define TRAILER_STRING "#-t-"
#define NAMESIZE 20 /* size of name allowed in header */
/*
The following depend on a properly defined notion of file type.
All strings should be the same length.
*/
#define ASCII_STRING "ascii "
#define LOCAL_STRING "local "
#define BINARY_STRING "binary"
#define ASCII 0
#define LOCAL 1
#define BINARY 2
/*
The file size (in chars) is computed for storage in the
archive headers, although this information is not used.
*/
/* GLOBAL VARIABLES */
char *fname [MAXFILES]; /* list of file names */
int fstat [MAXFILES]; /* status of each name in list */
int fcount; /* number of files on the list */
char chead [MAXLINE]; /* current header */
int errcnt; /* error count */
int verbose; /* YES if verbose flag on */
main (argc,argv)
int argc;
char **argv;
{
_allocp = NULL;
dioinit(&argc, argv);
main1(argc, argv);
dioflush();
}
main1(argc, argv)
int argc;
char **argv;
{
char *archive, *command;
int i;
/* initialize global error count */
errcnt = 0;
/* make sure there is at least a command and an archive name */
if (argc < 3) {
fprintf(STD_ERR, "too few arguments\n");
error (USAGE_MESSAGE);
}
/*
Put a list of file names into fnames [].
Check for duplicates.
*/
get_fnames(argc, argv);
/* point at the name of the archive */
archive = argv [2];
upper (archive);
/* point at the options list */
command = argv [1];
lower (command);
/* skip leading '-' if present */
if (command [0] == '-') {
i = 1;
}
else {
i = 0;
}
if (command [i + 1] == VERBOSE_CMD) {
verbose = YES;
}
else if (command [i + 1] == EOS) {
verbose = NO;
}
else {
fprintf(STD_ERR, "option too long\n");
error (USAGE_MESSAGE);
}
if (command [i] == UPDATE_CMD) {
update (archive);
}
else if (command [i] == TABLE_CMD) {
table (archive);
}
else if (command [i] == EXTRACT_CMD || command [i] == PRINT_CMD) {
extract (archive, command [i]);
}
else if (command [i] == DELETE_CMD) {
delete (archive);
}
else {
fprintf(STD_ERR, "unknown option\n");
error (USAGE_MESSAGE);
}
}
/* Add file 'name' to archive open on 'fd' */
add_file (name, fd)
char *name;
int fd;
{
char head [MAXLINE], trail[MAXLINE];
int nfd;
char nfbuf [BUFSIZ];
/* kludge for BDS C fopen */
nfd = nfbuf;
if (fopen (name, nfbuf) == ERROR) {
fprintf(STD_ERR, "can't add %s\n", name);
errcnt++;
return;
}
if (errcnt == 0) {
make_header (head, name);
if (verbose == YES) {
fprintf(STD_OUT, "%s\n", name);
}
put_line (head, fd);
copy_in (nfd, fd);
make_trailer (head, trail);
put_line (trail, fd);
}
fclose (nfd);
}
/*
Copy a file into an archive.
May have to be adjusted to allow for binary files.
*/
copy_in (fd, afd)
int fd, afd;
{
int c;
while (1) {
/* allow abort with ^C from console */
chkkey();
c = getc(fd);
if (c == ERROR || c == CPMEOF) {
break;
}
putc (c, afd);
}
}
/* Copy archive element from one archive to another */
copy_ele (oldafd, newafd)
int oldafd, newafd;
{
char line [MAXLINE];
while (get_line (line, oldafd) != 0) {
put_line (line, newafd);
if (ele_end (line) == YES) {
return;
}
}
remark ("archive integrity in doubt - missing trailer.\n");
errcnt++;
}
/* Copy a file out of an archive */
copy_out (afd, fd)
int afd, fd;
{
char line [MAXLINE];
int start;
while (get_line (line, afd) != 0) {
if (ele_end (line) == YES) {
/* we've copied the whole archive element */
return;
}
else {
put_line (line, fd); /* ordinary text */
}
}
remark ("archive integrity in doubt - missing trailer.\n");
errcnt++;
}
/* Delete files from the archive */
delete (aname)
char *aname;
{
int tprefx;
char tname [SYS_MAXFN];
int afd, tfd;
char afbuf [BUFSIZ], tfbuf[BUFSIZ];
/* kludge for BDS C fopen, fcreat */
afd = afbuf;
tfd = tfbuf;
tprefx = 0;
if (fcount <= 0) {
error ("delete by name only.\n");
}
if (fopen (aname, afbuf) == ERROR) {
cant (aname);
}
mkunik (tprefx, tname);
if (fcreat (tname, tfbuf) == ERROR) {
fprintf(STD_ERR, "can not create %s\n", tname);
}
replace (afd, tfd, DELETE_CMD);
not_found ();
fclose (afd);
putc (CPMEOF, tfd);
fflush (tfd);
fclose (tfd);
if (errcnt == 0) {
unlink (aname);
rename (tname,aname);
}
else {
remark ("fatal errors - archive not altered.\n");
}
unlink (tname);
}
/* Extract files from archive */
extract (archive, cmd)
char *archive, cmd;
{
char name [SYS_MAXFN], hdr[MAXLINE];
int afd, fd;
char afbuf [BUFSIZ], fbuf[BUFSIZ];
/* kludge for BDS C fopen, fcreat */
afd = afbuf;
fd = fbuf;
if (fopen (archive, afbuf) == ERROR) {
fprintf(STD_ERR, "can not open archive: %s\n", archive);
exit();
}
/* NOTE: this code could be much improved by keeping track of the
* number of files that have been extracted and exiting
* when all have been found.
*/
while (get_header (afd, hdr, name) != EOF) {
if (file_arg (name) == NO) {
skipf (afd);
}
else {
if (verbose == YES && cmd == PRINT_CMD) {
fprintf(STD_OUT, "%s\n", name);
}
else if (verbose == YES) {
fprintf(STD_OUT, "%s\n", name);
}
if (cmd == PRINT_CMD) {
copy_out (afd, STD_OUT);
}
else {
if (fcreat (name, fbuf) != ERROR) {
copy_out (afd, fd);
putc (CPMEOF, fd);
fflush (fd);
fclose (fd);
}
else {
fprintf(STD_ERR,
"can not create %s\n", name);
errcnt++;
skipf (afd);
}
}
}
}
not_found();
}
/* See if name is present in argument list */
file_arg (name)
char *name;
{
int i;
/* a null list matches ALL files */
if (fcount <= 0) {
return (YES);
}
for (i = 0; i < fcount; i++) {
if (strcmp (name, fname [i]) == 0) {
fstat [i] = YES;
return (YES);
}
}
return (NO);
}
/* Determine size of file (in chars) */
unsigned
fsize (name)
char *name;
{
int fd;
char fbuf [BUFSIZ];
unsigned count;
char line [MAXLINE];
int n;
/* kludge for BDS C fopen */
fd = fbuf;
if (fopen (name, fbuf) == ERROR) {
return (ERROR);
}
count = 0;
while (n = get_line(line, fd)) {
count += n;
}
fclose (fd);
return (count);
}
/*
Get file names into 'fname', check for duplicates.
File names are stored LOWER CASE.
*/
get_fnames(argc, argv)
int argc;
char **argv;
{
int ap, fp, len, i;
char line [MAXLINE];
for (fp = 0, ap = 3; ap < argc; ap++) {
fname [fp] = argv[ap];
if (fname [fp][0] == '-' && fname [fp][1] == EOS) {
while (fp < MAXFILES) {
/* get list from standard input */
len = get_line (line, STD_IN);
if (len <= 1) {
break;
}
/* remove the NEWLINE */
line [len-1] =EOS;
/* save it in dynamic storage */
fname [fp] = strsav (line);
lower (fname [f